//---------------------------------------------------------------------------

#include <vcl.h>
#include <mmsystem.h>
#pragma hdrstop

#include "var.h"
#include <stdio.h>
#include "SetPort.h"
#include "TestSerial.h"
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include <time.h>

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "iComponent"
#pragma link "iCustomComponent"
#pragma link "iPlot"
#pragma link "iPlotComponent"
#pragma link "iVCLComponent"
#pragma link "iLed"
#pragma link "iLedRound"
#pragma link "iComponent"
#pragma link "iCustomComponent"
#pragma link "iLed"
#pragma link "iLedRound"
#pragma link "iPlot"
#pragma link "iPlotComponent"
#pragma link "iVCLComponent"
#pragma resource "*.dfm"

extern char InBuffer[SERIAL232NUM][300];
extern char OutBuffer[SERIAL232NUM][300];

#define SAVE_PATH "c:\\test2.txt"

HANDLE hCOM[SERIAL232NUM];

TForm2 *Form2;
extern DWORD       nBytesRead;
extern DWORD       nBytesWrite;

TList* threadList= new TList;
TList* writeList = new TList;
FILE*  saveFile;   	//파일 포인터



//---------------------------------------------------------------------------
__fastcall TThreadBit::TThreadBit(void): TThread(true)
{
    FreeOnTerminate = true;
    Resume();
}

//---------------------------------------------------------------------------
void __fastcall  TThreadBit::Execute()  // 스레드
{
    char temp[2];
    temp[0] = NULL;
    temp[1] = NULL;

    while (!Terminated)
    {
        Application->ProcessMessages();
        for(int i = 0;i < SERIAL232NUM; i++)
        {
                if(!ReadFile(hCOM[i], &temp, 1, &nBytesRead, NULL))  // 수신하기
                {
                        Form2->iLedRound1->Active = false;           // 실행실패
                }
                if (temp[0] != NULL)
                {
                        if(temp[0] == 0x0D)
                        {
                                tindx = i;
                                Synchronize(UpdateRecv);
                        }
                        else
                        {
                                strcat(InBuffer[i],temp);
                        }
                }
        }

    Application->ProcessMessages();
    memset(temp, NULL, sizeof(temp));

    Sleep(0);

    } 
    return;
}


//---------------------------------------------------------------------------
void __fastcall  TThreadBit::UpdateRecv()  // 스레드
{
    // 0x05체크
    char temp[100];

    for(int i=0; i < tindx; i++)
    {
        if(InBuffer[tindx] != "0x0A")
        {
            strcat(temp,InBuffer[i]);
        }
    }

    Form2->Memo2->Lines->Add(InBuffer[tindx]);
    Form2->iLedRound2->Active = !Form2->iLedRound2->Active;

    memset(InBuffer[tindx],0x00,sizeof(InBuffer[tindx]));
}


//---------------------------------------------------------------------------
__fastcall TWriteThread::TWriteThread(void): TThread(true)
{
    FreeOnTerminate = true;
    Resume();
}

//---------------------------------------------------------------------------
void __fastcall  TWriteThread::Execute()  // 스레드
{
    float  i = 0;
    int outFile = FileCreate("c:\\test.txt");

    while (!Terminated)
    {
        // 랜덤 발생기
        randomize();
        float  x = random (10);
        char sTemp[10];
        sprintf(sTemp,"%f",x);

        if(WriteData(0, sTemp))
        {
        	Form2->Memo1->Lines->Add(sTemp);
        }
        else
        {
        	Form2->iLedRound2->Active = false;           // 실행실패
        	return;
        }

        Form2->FileSave(outFile, sTemp);

        // 그리그 그리기
        Form2->SetGrid(i, x);

        Application->ProcessMessages();

        Form2->iLedRound1->Active = !Form2->iLedRound1->Active;
        Sleep(1000);

        i++;
    }
    return;
}



//---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent* Owner)
        : TForm(Owner)
{
      saveFile = NULL;	// 파일포인터 초기화
}
//---------------------------------------------------------------------------


void __fastcall TForm2::FormCreate(TObject *Sender)
{
        StartAllThread();
}


//---------------------------------------------------------------------------
void TForm2::StartAllThread(void)
{
		 // 포트 기본설정

        iPlot1->Channel[0]->TitleText        = "AddYNow";
        iPlot1->XAxis[0]->Span               = 0.0001;
        iPlot1->Channel[0]->XAxisName        = "시리얼포트 테스트";
        iPlot1->TitleText                    = "시리얼포트 테스트";
        iPlot1->XAxis[0]->LabelsFormatStyle  = iptfDateTime;
        iPlot1->XAxis[0]->DateTimeFormat     = "yyyy-mm-yy hh:nn:ss";
        iPlot1->YAxis[0]->Min                = 0;
        iPlot1->YAxis[0]->Span               = 10;
        iPlot1->RemoveAllChannels();        // 모든 채널 삭제
        iPlot1->AddChannel();

        for(int i=0;i<SERIAL232NUM;i++)
                hCOM[i]=serial_init_com(i);

        WriteThread = new TWriteThread;
        ThreadBit 	= new TThreadBit;

        writeList->Add(WriteThread);
        threadList->Add(ThreadBit);

}
//---------------------------------------------------------------------------
void TForm2::StopAllThread(void)
{
        while(threadList->Count)
        {
                ((TThreadBit *)(threadList->Items[0]))->Terminate();
                threadList->Delete(0);
        }
        while(writeList->Count)
        {
                ((TWriteThread *)(writeList->Items[0]))->Terminate();
                writeList->Delete(0);
        }

        Form2->iLedRound1->Active = false;
        Form2->iLedRound2->Active = false;
}


//---------------------------------------------------------------------------
void __fastcall TForm2::Button1Click(TObject *Sender)
{
        // 포트가 닫혀 있을경우 포트 열려준다.
        for(int j=0; j < SERIAL232NUM; j++)
        {
                if(!hCOM[j])
                        serial_init_com(j);
        }

}
//---------------------------------------------------------------------------

void __fastcall TForm2::FormClose(TObject *Sender, TCloseAction &Action)
{
        StopAllThread();

        for(int i = 0; i < SERIAL232NUM; i++)
                serial_close_com(hCOM[i]);

}
//---------------------------------------------------------------------------
void TForm2::DelayTime(int iTime)
{
        int iFirst = timeGetTime();
        int iLast;

        while(iLast - iFirst < iTime)
        {
                iLast = timeGetTime();
                Application->ProcessMessages();
        }
}

//void __fastcall TForm1
void __fastcall TForm2::Button3Click(TObject *Sender)
{
       iPlot1->ClearAllData();
       Form2->Memo1->Clear();
       Form2->Memo2->Clear();
}
//---------------------------------------------------------------------------



void __fastcall TForm2::Button4Click(TObject *Sender)
{
        StopAllThread();
}
//---------------------------------------------------------------------------



void TForm2::SetGrid(float  time, float  number)
{
		char 	buffer[21];
        int 	count;

        iPlot1->Channel[0]->AddYNow(number);

        // 파일을 연후 파일에 저장한다.
        saveFile = fopen(SAVE_PATH,"a+");

        if (saveFile == NULL)
        {
         	ShowMessage("파일이 없습니다.");
         	return;
        }

        port_class.file_number = number;
        port_class.datetime =  Now();
        AnsiString sTemp = Now().CurrentDateTime();

        fprintf(saveFile, "%f#%s\n" , port_class.file_number,sTemp.c_str());

        if(saveFile)
        	fclose(saveFile);

}

void TForm2::FileSave(int file, char* message)
{
        // 파일을 연다.
        THandleStream*  outHandle;
        outHandle = new THandleStream(file);
        outHandle->Write(message, sizeof(message));

}

// 파일오픈
void __fastcall TForm2::Button5Click(TObject *Sender)
{
        int  size;
        char   c;
        char *str;
        FILE *file = NULL;  /* 파일 포인터 */
        char* ptoken;
        char* temp;
        TDateTime time_t;

        if(OpenDialog1->Execute())
        {
               // 모드초기화
               StopAllThread();
               iPlot1->ClearAllData();
               Memo1->Clear();
               Memo2->Clear();

               //  파일로드 한후 그리드 해준다.
               file=fopen(SAVE_PATH,"r");

               if (file == NULL)
               {
                ShowMessage("파일이 없습니다.");
                return;
               }

               str=NULL;
               size=0;    /* size변수에 0 저장 */

               while(!feof(file))
               {
                    c = fgetc( file );
                    if(c == EOF) break;

                        if (c=='\n')
                        {
                                if (str!=NULL)
                                {
                                        // 그리그 그려준다.
                                        ptoken = strtok(str, "#");
                                        temp    = ptoken;
                                        AnsiString stoken  = strtok( NULL, "#" );
                                        time_t  = stoken;

                                        // 그리그 그려준다.
                                        Memo1->Lines->Add(temp);
                                        Memo2->Lines->Add(time_t);

                                        iPlot1->Channel[0]->AddXY(time_t,(float)atof(temp));
                                        free(str);
                                }

                                str=NULL;  /* str에 NULL을 저장한다. */
                                size=0;    /* size에 0을 저장 */
                        }
                        else
                        {
                                size++;
                                str=(char *)realloc(str,(size+1)*sizeof(char));
                                str[size-1]=c;
                                str[size]='\0';
                        }
               }

               if (str!=NULL) free(str);
               fclose(file);
        }
}
//---------------------------------------------------------------------------
// 리셋버튼
void __fastcall TForm2::Button2Click(TObject *Sender)
{
       // 모든 내용을 지운다.
       iPlot1->ClearAllData();
       Form2->Memo1->Clear();
       Form2->Memo2->Clear();

       for(int i=0;i<SERIAL232NUM;i++)
                serial_close_com(hCOM[i]);
                
       StopAllThread();
       StartAllThread();
}
//---------------------------------------------------------------------------


